﻿using System;
using System.Collections.Generic;
using System.Linq;
using GalaSoft.MvvmLight.Ioc;
using IkeCode.WP7.HQReader.Base;
using IkeCode.WP7.HQReader.Interfaces;
using IkeCode.WP7.HQReader.Model;
using IkeCode.WP7.Toolkit.Persist;
using IkeCode.WP7.Toolkit;
using System.Windows;
using System.Text.RegularExpressions;
using IkeCode.WP7.Toolkit.HttpRequest;

namespace IkeCode.WP7.HQReader.Services
{
    /// <summary>
    /// Class that contains Feed Publisher actions
    /// </summary>
    public class FeedPublisherDataService : BaseDataService, IFeedPublisherDataService
    {
        IcSmartPersistService _smartPersistService;
        IcLoadingService _loadingService;

        /// <summary>
        /// Default constructor
        /// </summary>
        public FeedPublisherDataService()
        {
            _smartPersistService = SimpleIoc.Default.GetInstance<IcSmartPersistService>();
            _loadingService = SimpleIoc.Default.GetInstance<IcLoadingService>();
        }

        /// <summary>
        /// Get a list of Publishers
        /// </summary>
        /// <param name="callback">Callback with result or Exception object in error case</param>
        public void GetPublishers(Action<List<IIcFeedPublisher>, Exception> callback)
        {
            try
            {
                _loadingService.LoadingSwitch(true);

                var items = _smartPersistService.LoadObjectList<IcFeedPublisherModel, IIcFeedPublisher>("publishers.json");

                _loadingService.LoadingSwitch(false);

                callback(items, null);
            }
            catch (Exception e)
            {
                _loadingService.ErrorSwitch();
                callback(null, e);
            }
        }

        /// <summary>
        /// Save Publisher to Isolated Storage
        /// </summary>
        /// <param name="publisher">Publisher object</param>
        /// <param name="callback">Callback with same Publisher object or Exception object in error case</param>
        public void PostPublisher(IIcFeedPublisher publisher, Action<IIcFeedPublisher, Exception> callback)
        {
            try
            {
                publisher.Url = publisher.Url.NormalizeUrl();
                if (Regex.IsMatch(publisher.Url.ToString(), "(feed|atom|.xml)"))
                {
                    AsyncCall.Get.String(publisher.Url, (stringContent, error) =>
                    {
                        if (error != null)
                        {
                            throw error;
                        }
                        else
                        {
                            var publishers = new List<IIcFeedPublisher>();
                            this.GetPublishers((pubs, e) =>
                            {
                                if (pubs != null)
                                {
                                    publishers = pubs;
                                }
                            });

                            var url = publisher.Url.Host;
                            if (publishers.Any(i => i.Id == publisher.Id) || publishers.Any(i => i.Url == publisher.Url))
                            {
                                _smartPersistService.UpdateObject<IcFeedPublisherModel, IIcFeedPublisher>(publisher.Id, publisher);
                            }
                            else
                            {
                                _smartPersistService.AddObject<IcFeedPublisherModel, IIcFeedPublisher>(publisher, "publishers.json");
                            }

                            callback(publisher, null);
                        }
                    });
                }
                else
                {
                    throw new IcInvalidUrlException("Feed Url is invalid");
                }
            }
            catch (Exception e) { callback(null, e); }
        }

        /// <summary>
        /// Delete publisher
        /// </summary>
        /// <param name="publisher">Publisher to delete</param>
        /// <param name="callback">Action callback, returns boolean</param>
        /// <param name="showConfirmation">Show confirmation message flag</param>
        public void DeletePublisher(IIcFeedPublisher publisher, Action<bool, Exception> callback, bool showConfirmation = false)
        {
            try
            {
                var result = false;

                var message = MessageBox.Show("Are you sure you want to delete?", "Are you sure?", MessageBoxButton.OKCancel);
                if (showConfirmation)
                {
                    switch (message)
                    {
                        case MessageBoxResult.Cancel:
                        case MessageBoxResult.No:
                        case MessageBoxResult.None:
                            break;
                        case MessageBoxResult.OK:
                        case MessageBoxResult.Yes:
                            result = _smartPersistService.DeleteObject<IcFeedPublisherModel, IIcFeedPublisher>(publisher, "publishers.json");
                            break;
                        default:
                            break;
                    }
                }

                callback(result, null);
            }
            catch (Exception e) { callback(false, e); }
        }
    }
}